package com.longteng.testng.param;

import com.beust.jcommander.internal.Maps;
import com.longteng.common.ClassFilter;
import com.longteng.common.ClassFinder;
import com.longteng.testng.TxtGenerator;
import com.longteng.testng.annotation.Suffix;
import com.longteng.testng.annotation.SuffixHandler;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.longteng.common.ClassFilter.withAnnotation;
import static com.longteng.common.ClassFilter.withInherit;

/**
 * Created by sky on 15-12-24
 */
public class ProxyGenerator implements IGenerator{

    private Map<String,IGenerator> pairs = Maps.newHashMap();

    private String defaultSuffix;

    public void setDefaultSuffix(String suffix){
        this.defaultSuffix = suffix;
    }

    private ProxyGenerator() {
        this.defaultSuffix  = "txt";
        load();
    }

    private static ProxyGenerator proxyGenerator;

    public static ProxyGenerator getInstance(){
        if(proxyGenerator==null){
            synchronized (ProxyGenerator.class){
                if(proxyGenerator==null){
                    proxyGenerator = new ProxyGenerator();
                }
            }
        }
        return proxyGenerator;
    }

    @Override
    public List<Row> generate(Method method) {
        try{
            if(!method.isAnnotationPresent(Suffix.class)){
                return pairs.get(defaultSuffix).generate(method);
            }else{
                String suffix = method.getAnnotation(Suffix.class).value();
                IGenerator generator = pairs.get(suffix);
                if(generator==null){
                    throw new Exception("未找到suffix的处理类");
                }
                return generator.generate(method);
            }
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }

    public void registerGenerator(String suffix,IGenerator generator){
        this.pairs.put(suffix,generator);
    }

    @SuppressWarnings("unchecked")
    private void load(){
        Set<Class<?>> classes = ClassFinder.finder().filter(ClassFilter
                .filter(withAnnotation(SuffixHandler.class).and(withInherit(IGenerator.class)))).find();
        classes.forEach(it -> {
            try {
                pairs.put(it.getAnnotation(SuffixHandler.class).value(), (IGenerator) it.newInstance());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
    }
}
